<?php

namespace App\Http\Controllers;

use App\Imports\DailyImport;
use App\Models\CommissionLog;
use App\Models\MiyouDaily;
use App\Models\MiyouUser;
use App\Models\Users;
use App\Models\VerifyCode;
use App\Models\Withdraw;
use App\User;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

class UserController extends Controller
{

    public function postLogin()
    {
        $mobile = $this->request->input('mobile');
        $password = $this->request->input('password');
        $admin = (int)$this->request->input('admin', 0);
        if(empty($mobile) || empty($password)) {
            return $this->error("手机号或密码不能为空");
        }
        $user = Users::getByMobile($mobile, $admin);
        if(empty($user)) {
            return $this->error("手机号未注册" . ($admin ?'管理员' : ''));
        }
        if($user->state) {
            return $this->error("账户已禁用，请联系客服处理");
        }
        if(!password_verify($password, $user->password)) {
            return $this->error("密码错误");
        }
        $token = $user->token ? $user->token : md5( uniqid($mobile) . rand(10000, 99999));
        Users::query()->where('id', $user->id)->update([
           'token' => $token,
           'login_time' => date('Y-m-d H:i:s'),
        ]);
        return $this->ok(['token' => $token]);
    }



    public function postRegister()
    {
        $mobile = $this->request->input('mobile');
        $password = $this->request->input('password');
        $repeatPassword = $this->request->input('repeat');
        $verifyCode = $this->request->input('code');
        $linkId = (int)$this->request->input('link_id');
        $nickname = $this->request->input('nickname');
        $gender = (int)$this->request->input('gender');
        if(empty($linkId)) {
            return $this->error("请联系客服索要邀请码");
        }
        if(empty($mobile) || empty($password)) {
            return $this->error("手机号或密码不能为空");
        }
        if(empty($verifyCode)) {
            return $this->error("请填写验证码");
        }
        if($password != $repeatPassword) {
            return $this->error("两次密码不一致");
        }
        if(Users::getByMobile($mobile)) {
            return $this->error("该号码已注册");
        }
        $verify = VerifyCode::getCode($mobile);
        if($verifyCode != $verify) {
            return $this->error("验证码错误");
        }
        $userId = Users::query()->insertGetId([
            'pid' => $linkId,
            'nickname' => $nickname,
            'gender' => $gender,
            'mobile' => $mobile,
            'password' => password_hash($password, PASSWORD_BCRYPT),
        ]);
        $this->addCommission($linkId, $userId);
        $this->generateImg($userId);
        return $this->ok(['userId' => $userId]);
    }

    private function addCommission($linkId, $userId) {
        $amount = 0.1;
        Users::query()->where('id', $linkId)->increment('commission', $amount);
        CommissionLog::query()->insert([
            'user_id' =>  $linkId,
            'amount' =>  $amount,
            'type' =>  CommissionLog::TYPE_XIAJI,
            'create_time' => date('Y-m-d H:i:s'),
            'tag' => $userId
        ]);
    }


    public function generateImg($userId){
        $mergePath = base_path('public/qrcode/' . $userId . '.jpg');
        if(file_exists($mergePath)) {
            return;
        }
        $host = $this->request->getHost();
        $url = 'http://' . $host . '/register.html?link_id=' . $userId;
        $qrcodePath = storage_path('qrcode/' . $userId . '.png');
        app('qrcode')->format('png')->margin(0)->size(155)->generate($url, $qrcodePath);
        $basePath = storage_path('qrcode/base.jpg');
        $imageBase = imagecreatefromjpeg($basePath);
        $imageQr = imagecreatefrompng($qrcodePath);
        imagecopymerge($imageBase, $imageQr, 162, 492, 0,0, imagesx($imageQr), imagesy($imageQr), 100);
        imagejpeg($imageBase, $mergePath);
    }

    public function tuiguang(){
        $userId = $this->userId();
        $this->generateImg($userId);
        return view('public.tuiguang', ["userId" => $userId]);
    }

    public function postForget()
    {
        $mobile = $this->request->input('mobile');
        $password = $this->request->input('password');
        $repeatPassword = $this->request->input('repeat');
        $verifyCode = $this->request->input('code');
        if(empty($mobile) || empty($password)) {
            return $this->error("手机号或密码不能为空");
        }
        if($password != $repeatPassword) {
            return $this->error("两次密码不一致");
        }
        $verify = VerifyCode::getCode($mobile);
        if($verifyCode != $verify) {
            return $this->error("验证码错误");
        }
        $userId = Users::query()->where('mobile', $mobile)->update(['password' => password_hash($password, PASSWORD_BCRYPT)]);
        return $this->ok(['userId' => $userId]);
    }



    public function sendCode()
    {
        $mobile = $this->request->input('mobile');
        $ip = ip2long($this->request->getClientIp());
        $recent = VerifyCode::query()->where('ip', $ip)
            ->where('send_time', '>=', time() - 60)
            ->first();
        if($recent) {
            return $this->error("操作频繁 请稍后再试");
        }
        $row = VerifyCode::query()->where('mobile', $mobile)->first();
        $sendCount = $row ? $row->send_count : 0;
        if($sendCount > 10) {
            return $this->error("超过当日最大发送次数");
        }
        $code = rand(100000, 999999);
        $lastSendTime = $row ? $row->send_time : 0;
        $arr = [
            'code' => $code,
            'ip' => $ip,
            'send_time' => time(),
            'send_count' => $lastSendTime > strtotime('today') ? $sendCount + 1 : 0,
        ];
        $msg = $this->send($mobile, $code);
        if($msg == '提交成功') {
            if($row) {
                VerifyCode::query()->where(['mobile' => $mobile])->update($arr);
            } else {
                $arr['mobile'] = $mobile;
                VerifyCode::query()->insert($arr);
            }
            return $this->ok(['msg' => '发送成功']);
        } else {
            return $this->error($msg);
        }
    }


    public function send($mobile, $code){
        if(empty($mobile)){
            return '手机号码不能为空';
        }
        $post_data = [
            'account' => 'C25723212',
            'password' => '5ee83ad66d25d0120d13007a5e54ef34',
            'mobile' => $mobile,
            //'content' => iconv("UTF-8","gbk//TRANSLIT","您的验证码是：{$code}。请不要把验证码泄露给其他人。"),
            'content' => "您的验证码是：{$code}。请不要把验证码泄露给其他人。",
        ];
        $url = "http://106.ihuyi.com/webservice/sms.php?method=Submit";
        $ret = $this->curlPost($url, $post_data);
        app('log')->info('send_mail' . $ret);
        $xml = simplexml_load_string($ret);
        $xmljson = json_encode($xml);
        $arr = json_decode($xmljson,true);
        return $arr['msg'] ?? '';
    }


    public function curUser(){
        $user = $this->userInfo();
        $user->all_user = $this->getBottomUser($user['id']);
        $user->direct_user = self::$directUser;
        $user->second_user = self::$secondUser;
        return view('public.user', ['user' => $user]);
    }

    protected static $directUser = 0;
    protected static $secondUser = 0;

    protected function getBottomUser($uid, $depth = 0){
        $userList = $this->getUserArr($uid);
        if(empty($userList)) {
            return 0;
        }
        $totalCount = count($userList);
        if($depth == 0) {
            self::$directUser = $totalCount;
        }
        if($depth == 1) {
            self::$secondUser += $totalCount;
        }
        foreach ($userList as $key => $v){
            $totalCount += $this->getBottomUser($v['id'], $depth + 1);
        }
        return $totalCount;
    }

    protected function getUserArr($id){
       return  User::query()->where(['pid' => $id])->select(['id', 'pid'])->get()->toArray();
    }


    public function userList(){
        $model = User::query()->orderBy('id', 'desc')
            ->leftJoin('miyou_user', 'users.mobile', '=', 'miyou_user.mobile');
        $type = $this->request->input('type', 't');
        $mobile = $this->request->input('mobile');
        if(strlen($mobile) > 0) {
            $fieldMap = [
                't' => 'users.mobile',
                'x' => 'miyou_user.miyou_id',
                'i' => 'users.id',
                'p' => 'users.pid',
            ];
            $model = $model->where($fieldMap[$type], 'like', "%{$mobile}%");
        }
        $list = $model->selectRaw('users.*,miyou_user.miyou_id')->paginate(10)->toArray();
        foreach ($list['data']  as $k => $v) {
            $list['data'][$k]['total_commission'] = $v['commission'] + Withdraw::query()->where('user_id', $v['id'])->sum('amount');
            $list['data'][$k]['display_reward_rate'] = Users::getRewardRate($v['achievement'], $v['all_user'], $v['reward_rate']);
        }
        return $this->ok($list);
    }


    public function miyouUserList(){
        $model = MiyouUser::query()->orderBy('id', 'desc');
        $state = $this->request->input('state');
        $mobile = $this->request->input('mobile');
        if(strlen($mobile) > 0) {
            $model = $model->where('hide_mobile', 'like', "%{$mobile}%");
        }
        if(!is_null($state)) {
            $model = $model->where('state', $state);
        }
        $list = $model->paginate(10)->toArray();
        $stateMap = [
            0 => '未绑定',
            1 => '已绑定',
            2 => '绑定失败',
        ];
        foreach ($list['data']  as $k => $v) {
            $list['data'][$k]['state_txt'] = $stateMap[$v['state']] ?? '';
        }
        return $this->ok($list);
    }



    public function withdraw(){
        $userId = $this->userId();
        $amount = $this->request->input('amount');
        $real_name = $this->request->input('real_name');
        $zfb_account = $this->request->input('zfb_account');
        if($amount <= 0) {
            return $this->error("提现金额小于0");
        }
        if(empty($real_name) || empty($zfb_account))  {
            return $this->error("支付宝参数异常");
        }
        $exist = Withdraw::query()->where('user_id', $userId)
            ->where('create_time', '>=', date('Y-m-d', time() - 86400 * 2))
            ->count();
        if($exist) {
            return $this->error("3天内只能提现一次");
        }
        DB::beginTransaction();
        $res = Users::query()->where('id', $userId)->where('commission', '>=', $amount)
            ->decrement('commission', $amount);
        if(!$res) {
            DB::rollBack();
            return $this->error("可提现余额不足");
        }
        $withdrawId = Withdraw::query()->insertGetId([
            'user_id' => $userId,
            'amount' => $amount,
            'status' => Withdraw::STATUS_WAIT,
            'real_name' => $real_name,
            'zfb_account' => $zfb_account,
        ]);
        CommissionLog::query()->insert([
            'user_id' =>  $userId,
            'amount' =>  -$amount,
            'type' =>  CommissionLog::TYPE_WITHDRAW,
            'create_time' => date('Y-m-d H:i:s'),
            'tag' => $withdrawId
        ]);

        DB::commit();
        return $this->ok();
    }


    public function recommend(){
        $sort = $this->request->input('sort', 'ta');
        $userId = $this->userId();
        $sortMap = [
          'ac' => 'my_achievement',
          'ta' => 'achievement',
          'tu' => 'all_user',
          'ct' => 'create_time',
        ];
        $userList = User::query()
            ->where('pid', $userId)
            ->leftJoin('miyou_user', 'users.mobile', '=', 'miyou_user.mobile')
            ->selectRaw('users.*,miyou_user.miyou_id')
            ->orderBy($sortMap[$sort] ?? 'achievement', 'desc')
            ->get();
        return view('public.recommend', ['userList' => $userList, 'sort' => $sort]);
    }

    public function uploadXls(){
        $file =  $this->request->file('file');
        $filePath = $file->move(storage_path('app'),uniqid() . '.' . $file->getClientOriginalExtension());
        $import = new DailyImport();
        Excel::import($import, $filePath);
        $successCount = 0;
        foreach ($import->getData() as $row) {
            if(strlen($row[1] ?? '') < 10) {
                continue;
            }
            if(($row[2] ?? 0) <= 0) {
                continue;
            }
            $successCount++;
            MiyouDaily::query()->updateOrCreate([
               'miyou_id' =>  $row[1],
               'calc_date' =>  date('Y-m-d'),
            ], [ 'achievement' =>  $row[2]]);
        }
        @unlink($filePath);
        return $this->ok($successCount);
    }


    private function getUploadRow(){
        $file =  $this->request->file('file');
        $filePath = $file->move(storage_path('app'),uniqid() . '.' . $file->getClientOriginalExtension());
        $import = new DailyImport();
        Excel::import($import, $filePath);
        $ret = $import->getData();
        @unlink($filePath);
        return $ret;
    }

    public function commissionUpload(){
        $data = $this->getUploadRow();
        $successCount = 0;
        $noneUser = [];
        foreach ($data as $row) {
            $row = (array)$row;
            if(is_array(reset($row))) {
                $row = reset($row);
            }
            if(count($row) < 3) {
                continue;
            }
            $amount = $row[2];
            if(empty($row[1]) || empty($amount)) {
                continue;
            }
            if($row[0] == '昵称' && $row[1] == 'uuid') {
                continue;
            }
            $uuid = $row[1];
            $miyou = MiyouUser::query()->where('miyou_id', $uuid)->select(['mobile'])->first();
            if(empty($miyou->mobile ?? null)) {
                $noneUser[] = $uuid;
                continue;
            }
            $user = Users::query()->where('mobile', $miyou->mobile)->select('id')->first();
            if(empty($user)) {
                $noneUser[] = $uuid;
                continue;
            }
            $successCount++;
            Users::query()->where('id', $user->id)->increment('commission', $amount);
            CommissionLog::query()->insert([
                'user_id' =>  $user->id,
                'amount' =>  $amount,
                'type' =>  CommissionLog::TYPE_IN,
                'create_time' => date('Y-m-d H:i:s'),
                'tag' => implode("|", [
                    'xls', $amount
                ]),
            ]);
        }
        return $this->ok(['success' => $successCount, 'user' => $noneUser]);
    }


    public function commissionLog(){
        $userId = $this->userId();
        $logList = CommissionLog::query()->where('user_id', $userId)->orderBy('id', 'desc')
            ->get()->toArray();
        $map = [
            CommissionLog::TYPE_IN => '佣金收入',
            CommissionLog::TYPE_WITHDRAW => '提现',
            CommissionLog::TYPE_XIAJI => '新下级',
        ];
        foreach ($logList as $k => $v) {
            $logList[$k]['type_text'] = $map[$v['type']] ?? '';
            $logList[$k]['status'] = $v['type'] == CommissionLog::TYPE_IN ? '已到账' : $this->withdrawStatus($v['tag']);

        }
        return view('public.commission_log', ['logList' => $logList]);
    }

    private function withdrawStatus($withdrawId){
        $m = Withdraw::query()->find($withdrawId);
        if(empty($m)) {
            return '未知';
        }
        return $m->status == 0 ? '待转账' : '已到账';
    }

    public function withdrawList($download = false){
        $model = Withdraw::query()
            ->leftJoin('users', 'withdraw.user_id', '=', 'users.id');
        if(!$download && $mobile = $this->request->input('mobile')) {
            $model = $model->where('users.mobile', 'like', "%{$mobile}%");
        }
        $list = $model->selectRaw("withdraw.*,users.mobile,users.nickname")
             ->orderBy('withdraw.id', 'desc')->paginate(10)->toArray();
        $list['totalWithdraw'] = Withdraw::query()->sum('amount');
        return $this->ok($list);
    }



    private function withdrawArr(){
        $model = Withdraw::query()
            ->leftJoin('users', 'withdraw.user_id', '=', 'users.id');
        if($mobile = $this->request->input('mobile')) {
            $model = $model->where('users.mobile', 'like', "%{$mobile}%");
        }
        return $model->selectRaw("withdraw.*,users.mobile,users.nickname")
            ->orderBy('withdraw.id', 'desc')
            ->get()->toArray();
    }

    public function withdrawExcel(){
        $list = $this->withdrawArr(true);
        $date = date('Y-m-d');
        $file = storage_path("app/withdraw-{$date}.csv");
        $fp = fopen($file, 'w+');
        fputcsv($fp,  array_map(function ($v){
            return iconv('UTF-8', 'GBK//IGNORE', $v);
        }, ['微信昵称','手机号','金额','状态', '真实姓名', '支付宝账户', '提现时间']));
        foreach ($list as $v) {
            fputcsv($fp,  array_map(function ($v){
                return iconv('UTF-8', 'GBK//IGNORE', $v);
            }, [$v['nickname'], "\t" . $v['mobile'] . "\t", $v['amount'], $v['status'] == 0 ? '待转账' : '已转账',
                $v['real_name'], $v['zfb_account'], "\t" . $v['create_time'] . "\t"]));
        }
        fclose($fp);
        return response()->download($file);
    }


    public function userAchievement(){
        $model = CommissionLog::query()
            ->leftJoin('users', 'commission_log.user_id', '=', 'users.id')
            ->where('commission_log.type', CommissionLog::TYPE_IN);
        if($mobile = $this->request->input('mobile')) {
            $model = $model->where('users.mobile', 'like', "%{$mobile}%");
        }
        $list = $model->selectRaw("commission_log.*,users.mobile,users.nickname,users.nickname,users.td_achievement")
            ->orderBy('id', 'desc')->paginate(10)->toArray();
        foreach ($list['data']  as $k => $v) {
            $tagArr = explode("|", $v['tag']);
            $list['data'][$k]['direct_td_achievement'] = $tagArr[0] ?? 0;
            $list['data'][$k]['td_achievement'] = $tagArr[1] ?? 0;
            $list['data'][$k]['tag'] = substr($v['create_time'], 0, 10);
        }
        return $this->ok($list);
    }

    public function profit(){
        $model = MiyouDaily::query()
            ->leftJoin('miyou_user', 'miyou_daily.miyou_id', '=', 'miyou_user.miyou_id');
        if($mobile = $this->request->input('mobile')) {
            $model = $model->where('miyou_user.hide_mobile', 'like', "%{$mobile}%");
        }
        $list = $model->selectRaw("miyou_daily.*,miyou_user.mobile,miyou_user.nickname,miyou_user.hide_mobile")
            ->orderBy('miyou_daily.id', 'desc')->paginate(10)->toArray();
        return $this->ok($list);
    }

    public function confirmWithdraw(){
        $id = $this->request->input('id');
        Withdraw::query()->where('id', (int)$id)->update(['status' => Withdraw::STATUS_OK]);
        return $this->ok([]);
    }



    public function userEdit(){
        $id = $this->request->input('id');
        $data = $this->request->input();
        unset($data['id']);
        $miyouId = $data['miyou_id'];
        unset($data['miyou_id']);
        $user = Users::query()->find($id);
        if($user &&  $miyouId) {
            MiyouUser::query()->updateOrCreate(['mobile' => $user->mobile], [
                'miyou_id' => $miyouId
            ]);
        }
        Users::query()->where('id', (int)$id)
            ->update($data);
        return $this->ok([]);
    }

    public function userBind(){
        $id = $this->request->input('id');
        $mobile = $this->request->input('mobile');
        MiyouUser::query()->where('id', (int)$id)
            ->update(['mobile' => $mobile, 'state' => 1]);
        return $this->ok([]);
    }


    public function withdrawPage(){
        $data['user'] = $this->userInfo();
        $withdraw = Withdraw::query()->where('user_id', $this->userId())
            ->orderBy('id', 'desc')->limit(1)->first();
        $data['real_name'] = $withdraw ? $withdraw->real_name : '';
        $data['zfb_account'] = $withdraw ? $withdraw->zfb_account : '';
        return view('public.withdraw', $data);
    }

    public function setSession() {
        $sessionKey = $this->request->input('session_key');
        if(empty($sessionKey)) {
            $this->error("session_key不能为空");
        }
        file_put_contents(base_path("ht_session"), $sessionKey);
        $this->ok([]);
    }


}
